/*************************************************************************
	> File Name: zombie_1.c
	> Author: Angel Criss
	> Blog: blog.abbycin.tk 
	> Created Time: Tue 08 Jul 2014 08:13:56 PM CST
 ************************************************************************/
#define _XOPEN_SOURCE 700 // strsignal
#include"head.h"
#include<string.h> // unsafe

static volatile int num_zombie=0;

void dealing(int sig)
{
    int status,savedErr;
    pid_t zombie_pid;
    savedErr=errno;
    printf("got singal : %d (%s)\n",sig,strsignal(sig));
    while((zombie_pid=waitpid(-1,&status,WNOHANG))>0)
    {
        printf("reaped zombie [%d], then kill it\n",zombie_pid);
        p_wait_status(NULL,status);
        num_zombie--;
    }
    sleep(5);
    errno=savedErr;
}

int main(int argc,char *argv[])
{
    int num,i,ti=0;
    sigset_t blockset,emptyset;
    struct sigaction act;

                printf("(main) PPID: %d\n",getpid());

    sigemptyset(&act.sa_mask);
    act.sa_flags=0;
    act.sa_handler=dealing;

    sigaction(SIGCHLD,&act,NULL);

    sigemptyset(&blockset);
    sigaddset(&blockset,SIGCHLD);

    if(sigprocmask(SIG_SETMASK,&blockset,NULL)==-1)
        err("sigprocmask");

    num=(argc>1)?atoi(argv[1]):1;
    num_zombie=argc-1;

    for(i=1;i<=num;i++)
    {
        switch(fork()){
            case -1:
                err("fork");
            case 0:
                sleep(i+1);
                printf("zombie %d --> PID: %d\n",i,getpid());
                _exit(EXIT_SUCCESS);
            default:
                break; // do nothing just execute loop
        }
    }
    sleep(2);
    sigemptyset(&emptyset);

    while(num_zombie>0)
    {
    if(sigsuspend(&emptyset)==-1 & errno != EINTR)
       err("sigsuspend");
    ti+=1;
    }
    printf("killing \e[42m%d\e[0m time(s)\n",ti);
    exit(EXIT_SUCCESS);
}
